package com.ncmmall.api.apis.mall.wechat;


import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ncmmall.api.apis.service.Result;
import com.ncmmall.api.security.Securitys;
import com.ncmmall.application.business.member.MemberApplication;
import com.ncmmall.application.util.HttpRequests;
import com.ncmmall.cache.redis.RedisService;
import com.feijin.commons.lang.Requires;
import com.feijin.commons.webs.Webs;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.domain.security.user.WebUserRepository;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author likaikai
 * @date 2019-05-13 19:53
 */
@RestController
@RequestMapping("/wechat")
@Slf4j
public class WechatApi {

    @Value("${wx.sub_appid}")
    private String appid;

    @Value("${wx.appSecret}")
    private String appSecret;

    @Autowired
    private WebUserRepository userRepository;

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private MemberApplication memberApplication;

    @Autowired
    private RedisService redisService;

    /**
     * 拖拖部落电商小程序使用，校验code 获取session_key和openid
     *
     * @param code 小程序登录code 临时凭证
     */
    @GetMapping("/code")
    public Result code(String code, HttpServletRequest request) {

        Result result = new Result();
        try {
            Requires.isTrue(StringUtils.isNotBlank(code), "code不能为空");
            String body = HttpRequests.get("https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code");

            if (StringUtils.isBlank(body)) {
                return result.fail().setMsg("微信响应为空");
            }

            JSONObject jsonObject = JSON.parseObject(body);
            if (jsonObject.get("session_key") != null) {

                String sessionKey = jsonObject.getString("session_key");
                String openId = jsonObject.getString("openid");

                if (Securitys.isLogin(request)) {
                    WebUser member = Securitys.user(request);
                    member.setOpenId(openId);
                    member.setWechatSessionKey(sessionKey);
                    userRepository.save(member);
                }

                return result.ok().inject(ImmutableMap.of("openId", openId, "sessionKey", sessionKey));
            }

            int errcode = jsonObject.getIntValue("errcode");
            switch (errcode) {
                case -1:
                    result.fail().setMsg("系统繁忙");
                    break;
                case 40029:
                    result.fail().setMsg("code无效");
                    break;
                case 40163:
                    result.fail().setMsg("code已被使用");
                    break;
                case 45011:
                    result.fail().setMsg("频率限制，每个用户每分钟100次");
                    break;
                default:
                    result.fail().setMsg(jsonObject.getString("errmsg"));
                    break;
            }
            return result;
        } catch (IllegalArgumentException e) {
            return result.fail().setMsg(e.getMessage());
        } catch (Exception e) {
            log.error("获取数据异常", e);
            return result.fail().setMsg(e.getMessage());
        }
    }


    /**
     * 拖拖部落app登录
     *
     * @param unionId 微信用户标识
     */
    @GetMapping("/app/login")
    public Result appLogin(String unionId) {
        Result result = new Result();
        try {
            Requires.isTrue(StringUtils.isNotBlank(unionId), "unionId不能为空");
            WebUser user = queryChannelService.queryOneEntity("select * from security_web_user where unionId = :unionId", ImmutableMap.of("unionId", unionId), WebUser.class);
            if (user == null) {
                return result.ok().inject(ImmutableMap.of("unionId", unionId));
            }

            user = memberApplication.login(user, Webs.getRemoteIp());
            return result.ok().inject(ImmutableMap.of("token", user.getAccessToken(), "refreshToken", user.getRefreshToken()));

        } catch (IllegalArgumentException e) {
            return result.fail().setMsg(e.getMessage());
        } catch (Exception e) {
            log.error("微信授权登录异常", e);
            return result.fail().setMsg("授权登录异常");
        }

    }


    /**
     * 绑定手机号码
     */
    @PostMapping("/app/bindPhone")
    public Result appLogin(@RequestBody WebUser params) {
        Result result = new Result();
        try {
            Assert.notBlank(params.getUnionId(), "unionid不能为空");
            Assert.notBlank(params.getMobile(), "手机号码不能为空");
            Assert.notBlank(params.getMobileCode(), "验证码不能为空");
            String code = redisService.get("msm-" + params.getMobile());
            if (StrUtil.isBlank(code) || !code.equals(params.getMobileCode())) {
                return result.fail().setMsg("验证码不正确");
            }
            WebUser user = memberApplication.appWechatRegister(params.getUnionId(), params.getMobile());
            user = memberApplication.login(user, Webs.getRemoteIp());
            return result.ok().inject(ImmutableMap.of("token", user.getAccessToken(), "refreshToken", user.getRefreshToken()));
        } catch (IllegalArgumentException e) {
            return result.fail().setMsg(e.getMessage());
        } catch (Exception e) {
            log.error("微信绑定手机号码异常", e);
            return result.fail().setMsg("绑定手机号码异常");
        }
    }


    /**
     * 扫码支付测试
     */
    @RequestMapping(value = "/scanPay", method = RequestMethod.GET)
    @ResponseBody
    public Result scanPay(String code, double amount) {
        Result result = new Result();
        try {
            //交易订单号
            String outTradeNo = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + RandomStringUtils.randomNumeric(6);
            //body信息
            String body = "90的便利店";
            WechatPayOrderResponse response = new WechatPay().scanCode(code, outTradeNo, body, amount);
            if ("SUCCESS".equals(response.getResult_code())) {
                return result.ok().inject(response);
            } else {
                return result.fail().inject(response);
            }
        } catch (Exception e) {
            log.error("[扫码支付测试异常]", e);
            return result.fail().setMsg("扫码支付测试失败");
        }

    }


}
